import axios, {AxiosError, type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, isCancel } from "axios"

import {MessagePlugin} from "tdesign-vue-next";
import type {ErrorResponse} from "@/api/types";
import {useAppStore} from "@/store";

const BASE_URL: string = import.meta.env.VITE_API_BASE_URL;

// 实例
const instance: AxiosInstance = axios.create({
    baseURL: BASE_URL,
    timeout: 60000,
});

// 只需要最新的请求数据，并且中断上一个重复请求时，可以利用axios的CancelToken去中断之前的请求。
const cacheRequest = {};
// 删除缓存队列中的请求
function removeCacheRequest(reqKey) {
    if (cacheRequest[reqKey]) {
        // 通过AbortController实例上的abort来进行请求的取消
        cacheRequest[reqKey].abort()
        delete cacheRequest[reqKey]
    }
}

const tokenPrefix = "Bearer ";
// 拦截器
instance.interceptors.request.use(
    (request: AxiosRequestConfig) => {

        // 只需要最新的请求数据，并且中断上一个重复请求时，可以利用axios的CancelToken去中断之前的请求。
        const { url, method, removeCache = false } = request
        if (removeCache) {
            // 请求地址和请求方式组成唯一标识，将这个标识作为取消函数的key，保存到请求队列中
            const reqKey = `${url}&${method}`
            // 如果config传了需要清除重复请求的removeCache，则如果存在重复请求，删除之前的请求
            removeCacheRequest(reqKey)
            // 将请求加入请求队列，通过AbortController来进行手动取消
            const controller = new AbortController()
            request.signal = controller.signal
            cacheRequest[reqKey] = controller
        }

        // 添加 Authorization header
        const appStore = useAppStore();
        if (appStore.token && request.headers) {
            request.headers["Authorization"] = tokenPrefix + appStore.token;
        }
        return request;
    },
    error => {
        return Promise.reject(error);
    },
);

instance.interceptors.response.use(
    (response: AxiosResponse) => {

        // 只需要最新的请求数据，并且中断上一个重复请求时，可以利用axios的CancelToken去中断之前的请求。
        // 请求成功，从队列中移除
        const { url, method, removeCache = false } = response.config
        if (removeCache) {
            removeCacheRequest(`${url}&${method}`)
        }
        // 对响应数据做处理，例如只返回data部分
        const res = response.data;
        if (res.code === 200) {
            return res;
        } else {
            // 其他状态码都当作错误处理
            // 可以在这里对不同的错误码进行不同处理
            return Promise.reject({
                message: res.message || 'Error',
                status: res.code
            });
        }
    },
    async (error: AxiosError<ErrorResponse>) => {

        if (isCancel(error)) {
            // 通过CancelToken取消的请求不做任何处理
            return Promise.reject({
                message: '重复请求，自动拦截并取消',
                code: 66666,
            });
        }
        //const responseData: ErrorResponse
        //await MessagePlugin.error(error.message);
        //await MessagePlugin.error(error.response?.data.msg); // AxiosError<AxiosResponse>
        const responseData: ErrorResponse | undefined = error.response?.data;
        responseData && await MessagePlugin.error(responseData.msg);
        if (error.response?.status === 401) {
            const appStore = useAppStore();
            await appStore.logout();

            // todo 无感刷新令牌
            // 获取token失效的401 错误的请求地址
            /*const originalRequest = error.config;
            try {
                // 尝试刷新 token
                const refreshToken = localStorage.getItem('refreshToken');
                const response = await axios.post('/api/token/refresh', { token: refreshToken });
                // 更新 access token
                const newAccessToken = response.data.accessToken;
                localStorage.setItem('accessToken', newAccessToken);
                // 更新原请求的 token
                originalRequest.headers['Authorization'] = `Bearer ${newAccessToken}`;
                // 重试原请求
                return instance(originalRequest);

            } catch (refreshError) {
                console.error('Token refresh failed:', refreshError);
                // 处理刷新失败，例如重定向到登录页面
            }*/
        }
        //return Promise.reject(error);
        return Promise.reject({
            message: error.message || 'Error',
            code: 999999
        });
    }
);

export default instance;